using UnityEngine;
using System.Collections;

//MAKE SURE THE TAG 'FRUIT' IS MADE AND ASSIGNED TO ALL FRUITS
public class Tower: PlaceableObject
{
	public AudioClip spawnSound;
	public AudioClip fireSound;
	public GameObject projectile;
	//Call aiysha's sprite script.
	
	public float health;				//Health of tower
	public float defaultRadius = 1.5F;	//Default radius of tower collider
	public float maxHealth = 100.0F;	//Max Health of tower
	public bool animate;				
	public float deAggroRange = 20.0F;	//The de-aggro range is > the aggro range specified by the collider's radius
	public float aggroRange = 5.0F;		//The aggro range of tower
	
	private GameObject target;			//Object it's targeting
	private Vector3 boundingBoxMin;
	private Vector3 boundingBoxMax;
	public float sizeB_x = 4F;
	public float sizeB_y = 4F;
	
	
	public float GCD = 1F;
	private float timer = 1F;
	
	public float buildTimer = 10F;		//10 seconds build time.
	
	//Input tower sprites
	
	enum TowerState
	{
		_idle = 1,
		_attack = 2,
		_death = 3,		
		_building = 4,
	};
	
	protected enum ElementType
	{
		_A,
		_B,
		_C,
		_D,
		_E,
		_F,
		_G,
	};
	
	protected ElementType elementType;		//Element type of this tower
	protected ElementType[] strongAgainst;	//Elements it's strongest against
	private TowerState state;				//State of tower
	
	// Use this for initialization
	void Start () 
	{
		target = null;
		this.gameObject.AddComponent <SphereCollider> ();
		this.gameObject.GetComponent <SphereCollider> ().radius = defaultRadius;
		
		//This if condition is just to ensure if the tower is tagged as tower.
		if ( this.gameObject.tag != "tower" )
			this.gameObject.tag = "tower";
		
		state = TowerState._building;
		strongAgainst = new ElementType[2];
		
		boundingBoxMin = new Vector3 ( this.transform.position.x - sizeB_x, this.transform.position.y + sizeB_y, this.transform.position.z );
		boundingBoxMax = new Vector3 ( this.transform.position.x + sizeB_x, this.transform.position.y - sizeB_y, this.transform.position.z );
	}
	
	void Awake ()
	{
		//Check if all the corresponding sprites are here before activating.
		if ( !projectile )
			Debug.Log ( "Warning! You have not equiped a projectile to this tower! " );
	}
	
	// Update is called once per frame
	void Update () 
	{	
		if ( state == Tower.TowerState._building )
		{
			if ( buildTimer > 0 )
				buildTimer -= Time.deltaTime;
			
			if ( buildTimer < 0 )
			{
				buildTimer = 0;
				state = Tower.TowerState._idle;
				Debug.Log ( "BUILDING COMPLETE!" );
			}
		}
		else
		{
			//For now it's just search for nearest enemy by distance.
			if ( target )
			{
				state = Tower.TowerState._attack;
				if ( ( target.gameObject.transform.position - this.gameObject.transform.position ).magnitude > deAggroRange )
				{
					//Stop attacking once it's out of aggro range.
					target = null;
					state = TowerState._idle;
				}
				else
				{
				
				}			
			}
		}
		
	}
	
	//If some nutsack is in aggro range.
	void OnCollisionEnter ( Collision hit )
	{
		/*
		//Check if the tag of the object intersected with is an enemy
		if ( hit.gameObject.tag == "enemy" )
		{
			//Target in sight! Register target! Prepare to attack!
			//PEW PEW JUICE on enemy
			target = hit.gameObject;														//set target to hit.gameobject
			state = TowerState._attack;														//Change towerstate to attacking state.
			Vector3 location =  hit.gameObject.transform.position;
			
		}*/
	}
	
	public void setShootingRange ( float range )
	{
		this.gameObject.GetComponent<SphereCollider>().radius = range;
	}
	
	public float getShootingRange ()
	{
		return this.gameObject.GetComponent<SphereCollider>().radius;
	}
	
	public void setDeAggroRange ( float range )
	{
		deAggroRange = range;	
	}
	
	public float getAggroRange ()
	{
		return deAggroRange;
	}
	
	//Health manipulation
	public void setHealth ( float hp )
	{
		health = hp;
	}
	
	public void SubHealth ( float diff )
	{
		if ( ( health - diff ) > 0 )
			health = health - diff;
		else
		{
			health = 0.0F;
			destroyObject();
		}
	}
	
	public void AddHealth ( float diff )
	{
		if ( ( health + diff ) < 100 )
			health  = health + diff;
		else
			health = maxHealth;
	}
	
	public float getHealth ()
	{
		return health;
	}
	//Health manipulation
	
	
	public void playSound ()
	{
		if ( fireSound )
			this.gameObject.GetComponent<AudioSource>().PlayOneShot( fireSound );
		else
			Debug.Log ( "WARNING!!! NO SOUND AVAILABLE! ");
	}
	
	//Use this function to fire the projectile
	public void oneRoundAway()
	{
		if ( fireSound )
					this.gameObject.GetComponent<AudioSource>().PlayOneShot ( fireSound );
		else
				Debug.Log ( "WARNING!!! NO SOUND AVAILABLE! ");		
		searchByNearest();
		if ( projectile && target )	
		{	
			GameObject bullet = (GameObject)Instantiate ( projectile, target.transform.position, Quaternion.identity );
			//play attack sprites			
			bullet.GetComponent<Projectile>().setTarget ( target );
			bullet.GetComponent<Projectile>().fire();
		}
	}
	
	//This function searches for the nearest targeted enemy and assigns it to target variable
	public void searchByNearest (  )
	{
		float distance = 0F, lowestDistance = 0F;
		
		//The whole list of enemies within the scene
		GameObject[] listOfEnemies = GameObject.FindGameObjectsWithTag ("enemy");
		GameObject[] listOfEnemies2 = new GameObject[listOfEnemies.Length];
		int count = 0;
		foreach ( GameObject enemy in listOfEnemies )
		{
			//Check if each enemy reside within the AABB of this tower.
			if ( enemy.transform.position.x > -sizeB_x && enemy.transform.position.x < sizeB_x )
			{
				if ( enemy.transform.position.y > -sizeB_y && enemy.transform.position.y < sizeB_y )
				{
					listOfEnemies2[count] = enemy;	//Place all enemies within the AABB to listOfenemies2 list
					count++;
				}
			}
		}
		
		//Hopefully, this helps to reduce the computation time
		if ( listOfEnemies.Length > 0 )
		{
			foreach ( GameObject enemy in listOfEnemies2 )
			{
				distance = ( enemy.transform.position - this.transform.position ).magnitude;
				if ( distance < aggroRange )
				{
					if ( distance < lowestDistance )
					{
						target = enemy;
						lowestDistance = distance;	
					}
				}
			}
		}
	}
	
	public bool isTarget ()
	{
		if ( target )
			return true;
		else
			return false;
	}
	
	public void call_Aiyshas_sprite_script_to_play_animations ()
	{
	}
	
	
}
